﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using CartoGraphic.Model2;
using CartoGraphic.MyTool;
using CartoGraphic.Model;

namespace CartoGraphic
{
    public partial class MainForm : Form
    {
        public static Dictionary<string, string> symbolCode;  //编码索引
        public static Dictionary<string, string> infoCode;
        List<AbstractGeometry> geos;
        DataFrame frame;
        Dictionary<string, Layer> layers;
        Layer bLayer, cLayer, fLayer, hLayer, rLayer, tLayer, vLayer, uLayer;
        DrawArea drawArea;

        //读取编码索引
        private void readCode()
        {
            try
            {
                symbolCode = new Dictionary<string, string>();
                infoCode = new Dictionary<string, string>();
                StreamReader sr = new StreamReader(@"code.csv", Encoding.GetEncoding("gb2312"));
                string sFile = sr.ReadToEnd();
                string[] vals = sFile.Split('\n');
                for (int i = 0; i < vals.Length; i++)
                {
                    string sLine = vals[i];
                    string[] sVal = sLine.Split(',');
                    if (sVal.Length < 3)
                        continue;
                    string key = sVal[0];
                    string value = sVal[2].Trim();
                    string value2 = sVal[3].Trim();
                    if (symbolCode.ContainsKey(key))
                        continue;
                    symbolCode.Add(key, value);
                    infoCode.Add(key, value2);
                }
                symbolCode.Add("32000", "U");
                infoCode.Add("32000", "U");
                symbolCode.Add("80000", "U");
                infoCode.Add("80000", "U");
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }

        }

        private void openDoc()
        {
            layers = new Dictionary<string, Layer>();
            bLayer = new Layer(1);
            cLayer = new Layer(0);
            fLayer = new Layer(4);
            hLayer = new Layer(3);
            rLayer = new Layer(2);
            tLayer = new Layer(5);
            vLayer = new Layer(6);
            uLayer = new Layer(7);
            layers.Add("建筑物", bLayer);
            layers.Add("图幅", cLayer);
            layers.Add("境界", fLayer);
            layers.Add("河流", hLayer);
            layers.Add("道路", rLayer);
            layers.Add("地貌", tLayer);
            layers.Add("植被", vLayer);
            layers.Add("未知", uLayer);



            frame = new DataFrame();
            geos = new List<AbstractGeometry>();
            OpenFileDialog dlg = new OpenFileDialog();
            //dlg.ShowDialog();
            dlg.FileName = "*.txt";
            dlg.Title = "打开文件";
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                FileInfo fi = new FileInfo(dlg.FileName);
                StreamReader sr = fi.OpenText();
                string s = sr.ReadLine();   //第一行读取上下左右边界
                string[] fls = s.Split(',');
                frame.left = Double.Parse(fls[0]);
                frame.down = Double.Parse(fls[1]);
                frame.right = Double.Parse(fls[2]);
                frame.up = Double.Parse(fls[3]);
                frame.g = panel2.CreateGraphics();
                frame.screenHeight = panel2.Height;
                frame.screenWidth = panel2.Width;
                sr.ReadLine();
                sr.ReadLine();
                //读取点的个数               
                while (sr.Peek() > 0)
                {
                    s = sr.ReadLine();
                    if (!s.Contains(" "))
                        continue;
                    string type = s.Split(' ')[0].Trim();
                    int count = Int16.Parse(s.Split(' ')[1].Trim());
                    if (count == 0)
                        continue;
                    if (type.Equals("Point"))
                    {
                        List<PointGeo> points = readPoint(sr, count);
                        geos.AddRange(points);
                    }
                    else if (type.Equals("Polyline"))
                    {
                        List<PolyLineGeo> lines = readLines(sr, count);
                        geos.AddRange(lines);
                    }
                    else if (type.Equals("Polygon"))
                    {
                        List<PolygonGeo> polygons = readPolygon(sr, count);
                        geos.AddRange(polygons);
                    }
                }
                sr.Close();
                //frame.geos = geos;
                frame.trans();

                foreach (AbstractGeometry geo in geos)
                {
                    string type = geo.type;
                    if (type.Equals("B"))
                        layers["建筑物"].geos.Add(geo);
                    else if (type.Equals("C"))
                        layers["图幅"].geos.Add(geo);
                    else if (type.Equals("F"))
                        layers["境界"].geos.Add(geo);
                    else if (type.Equals("H"))
                        layers["河流"].geos.Add(geo);
                    else if (type.Equals("R"))
                        layers["道路"].geos.Add(geo);
                    else if (type.Equals("T"))
                        layers["地貌"].geos.Add(geo);
                    else if (type.Equals("V"))
                        layers["植被"].geos.Add(geo);
                    else if (type.Equals("U"))
                        layers["未知"].geos.Add(geo);
                }
                for (int i = 7; i >=0; i--)
                {
                    foreach (KeyValuePair<string, Layer> pair in layers)
                    {
                        if (pair.Value.depth == i)
                            pair.Value.draw(frame.g);
                    }
                }
                foreach (ListViewItem item in listView1.Items)
                    listView1.Items.Remove(item);
                foreach (KeyValuePair<string, Layer> pair in layers)
                {
                    ListViewItem lvi = new ListViewItem();
                    lvi.Tag = pair.Value;
                    lvi.Text ="    "+pair.Key;
                    listView1.Items.Add(lvi);
                }
            }

        }

        private List<PointGeo> readPoint(StreamReader sr, int pointCount)
        {
            List<PointGeo> points = new List<PointGeo>();
            string s = "", codeInfo = "";
            double x, y;
            for (int i = 0; i < pointCount * 2; i++)
            {
                s = sr.ReadLine();
                if (i % 2 == 0)
                {
                    codeInfo = s.Trim();
                }
                if (i % 2 == 1)
                {
                    string[] locations = s.Split(',');
                    x = Double.Parse(locations[0]);
                    y = Double.Parse(locations[1]);
                    PointGeo geo = new PointGeo(new MyPoint(x, y), symbolCode[codeInfo]);
                    geo.info = infoCode[codeInfo];
                    points.Add(geo);
                }
            }
            return points;
        }

        private List<PolyLineGeo> readLines(StreamReader sr, int lineCount)
        {
            List<PolyLineGeo> lines = new List<PolyLineGeo>();
            string s = "";
            for (int i = 0; i < lineCount; i++)
            {
                List<MyPoint> linepoints = new List<MyPoint>();
                s = sr.ReadLine();
                string codeinfo = s.Trim();
                s = sr.ReadLine();
                int pointCount = Int16.Parse(s.Trim());
                for (int j = 0; j < pointCount; j++)
                {
                    s = sr.ReadLine();
                    double x = Double.Parse(s.Split(',')[0].Trim());
                    double y = Double.Parse(s.Split(',')[1].Trim());
                    linepoints.Add(new MyPoint(x, y));
                }
                PolyLineGeo line = new PolyLineGeo(linepoints);
                line.type = symbolCode[codeinfo];
                line.info = infoCode[codeinfo];
                lines.Add(line);
                sr.ReadLine();
            }
            return lines;
        }

        private List<PolygonGeo> readPolygon(StreamReader sr, int polygonCount)
        {
            List<PolygonGeo> lines = new List<PolygonGeo>();
            string s = "";
            for (int i = 0; i < polygonCount; i++)
            {
                List<MyPoint> linepoints = new List<MyPoint>();
                s = sr.ReadLine();
                string codeinfo = s.Trim();
                s = sr.ReadLine();
                int pointCount = Int16.Parse(s.Trim());
                for (int j = 0; j < pointCount; j++)
                {
                    s = sr.ReadLine();
                    double x = Double.Parse(s.Split(',')[0].Trim());
                    double y = Double.Parse(s.Split(',')[1].Trim());
                    linepoints.Add(new MyPoint(x, y));
                }
                PolygonGeo line = new PolygonGeo(linepoints);
                line.type = symbolCode[codeinfo];
                line.info = infoCode[codeinfo];
                lines.Add(line);
                sr.ReadLine();
            }
            return lines;
        }

        //所有图层绘制
        private void drawLayers()
        {
            for (int i = 7; i >= 0; i--)
            {
                foreach (KeyValuePair<string, Layer> pair in layers)
                {
                    if (pair.Value.depth == i)
                        pair.Value.draw(frame.g);
                }
            }
        }

        public MainForm()
        {
            InitializeComponent();
            drawArea = new DrawArea();
            drawArea.Owner = this;
            drawArea.Parent = panel2;
            drawArea.Location = new Point(0, 0);
            drawArea.Size = new Size(10, 10);
            drawArea.ActiveTool = DrawArea.DrawToolType.Line;
            this.Controls.Add(drawArea);
            readCode();
        }

        private void splitContainer3_Panel1_Paint(object sender, PaintEventArgs e)
        {

        }

        private void menuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {

        }

        private void 打开ToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void 保存ToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void 另存为ToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        //pan
        private void toolStripButton1_Click(object sender, EventArgs e)
        {

        }

        //scale
        private void toolStripButton2_Click(object sender, EventArgs e)
        {

        }

        private void 打开OToolStripButton_Click(object sender, EventArgs e)
        {
            openDoc();
        }

        private void 保存SToolStripButton_Click(object sender, EventArgs e)
        {

        }

        private void panel2_Paint(object sender, PaintEventArgs e)
        {
            
        }

        private void panel2_Resize(object sender, EventArgs e)
        {
            
        }

        private void treeView1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                //contextmenu.Show(treeView1, new Point(e.X, e.Y));
            }

        }

        private void 上移ToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void 下移ToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void 显示ToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void 关闭ToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

         

        private void treeView1_DragDrop(object sender, DragEventArgs e)
        {
            
        }

        private void treeView1_DragEnter(object sender, DragEventArgs e)
        {
            
        }

        private void treeView1_ItemDrag(object sender, ItemDragEventArgs e)
        {
            
        }

        private void treeView1_MouseUp(object sender, MouseEventArgs e)
        {

        }

        private void listView1_ItemDrag(object sender, ItemDragEventArgs e)
        {
            listView1.DoDragDrop(e.Item, DragDropEffects.Move);
        }

        private void listView1_DragDrop(object sender, DragEventArgs e)
        {
            ListViewItem item = (ListViewItem)e.Data.GetData(typeof(ListViewItem));           
            //listView1.Items.Add((ListViewItem)item.Clone());
            Point Position = new Point(e.X,e.Y);
            Position = listView1.PointToClient(Position);
            ListViewItem DropNode = this.listView1.GetItemAt(Position.X, Position.Y);
            listView1.Items.Insert(DropNode.Index, (ListViewItem)item.Clone());
            (DropNode.Tag as Layer).depth = DropNode.Index;
            (item.Tag as Layer).depth = item.Index;
            listView1.Items.Remove(item);
            for (int i = 7; i >= 0; i--)
            {
                foreach (KeyValuePair<string, Layer> pair in layers)
                {
                    if (pair.Value.depth == i)
                        pair.Value.draw(frame.g);
                }
            }
        }

        private void listView1_DragEnter(object sender, DragEventArgs e)
        {
            e.Effect = e.AllowedEffect;
        }

        private void panel2_Resize_1(object sender, EventArgs e)
        {
            if (layers == null)
                return;
            frame.screenHeight = panel2.Height;
            frame.screenWidth = panel2.Width;
            frame.trans();
            drawLayers();
        }

        private void panel2_Paint_1(object sender, PaintEventArgs e)
        {
            if (layers == null)
                return;
            drawLayers();
        }

    }
}
